package com.zhenwei.zscm.service;

import cn.hutool.core.net.URLEncodeUtil;
import com.zhenwei.zscm.common.base.RestMsg;
import com.zhenwei.zscm.common.base.RestResult;
import com.zhenwei.zscm.common.exception.CustomException;
import com.zhenwei.zscm.common.utils.Linq;
import com.zhenwei.zscm.config.SystemConfig;
import com.zhenwei.zscm.mappings.FileMapping;
import com.zhenwei.zscm.model.dto.file.FileDTO;
import com.zhenwei.zscm.repo.ExceptionLogRepo;
import com.zhenwei.zscm.repo.FileRepo;
import com.zhenwei.zscm.repo.LogRepo;
import lombok.AllArgsConstructor;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Service
@AllArgsConstructor
public class FileService {
    private FileRepo fileRepo;
    private LogRepo logRepo;
    private ExceptionLogRepo    exceptionLogRepo;
    private final String LOG_TYPE = "文件管理";
    public RestResult uploadFiles(List<MultipartFile> files) {
        // 格式化当前日期为 yyyyMMdd 格式
        String dateFolder = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));

        // 创建目标目录
        String targetDir = SystemConfig.fileBaseDir + File.separator + dateFolder;
        File dir = new File(targetDir);
        if (!dir.exists()) {
            var _ = dir.mkdirs();
        }
        try {
            var list = new ArrayList<FileDTO>();
            for (MultipartFile file : files) {
                if (!file.isEmpty()) {
                    // 获取原始文件名
                    String originalFilename = file.getOriginalFilename();
                    if (originalFilename != null) {
                        // 保存文件到目标目录
                        file.transferTo(new File(dir, originalFilename));
                    }

                    var dto = new FileDTO();
                    dto.setFileName(originalFilename);
                    dto.setFilePath(targetDir + File.separator + originalFilename);
                    dto.setFileSize(file.getSize());
                    dto.setFileType(getFileExtension(originalFilename));
                    list.add(dto);
                }
            }
            boolean saved = fileRepo.Save(list);
            if (!saved) {
                return RestResult.fail(RestMsg.UPLOAD_FAILED);
            }
            logRepo.createAsync(LOG_TYPE, "上传文件->" + Linq.select(list, FileDTO::getFileName));
            return RestResult.success(Linq.mapList(list, FileDTO::getGuid), 0);
        } catch (IOException e) {
            exceptionLogRepo.createAsync(LOG_TYPE, e.getMessage(), Arrays.toString(e.getStackTrace()));
            return RestResult.fail(RestMsg.UPLOAD_FAILED);
        }
    }

    private String getFileExtension(String filename) {
        if (filename == null || filename.isEmpty()) {
            return "";
        }
        int lastDotIndex = filename.lastIndexOf(".");
        if (lastDotIndex == -1 || lastDotIndex == filename.length() - 1) {
            return "";
        }
        return filename.substring(lastDotIndex);
    }

    public ResponseEntity<byte[]> download(String fileId) {
        FileDTO dto = fileRepo.getOne(fileId);
        if(dto == null) {
            throw new CustomException(RestMsg.FILE_NOT_EXISTS);
        }
        // 格式化日期参数为 YYYYMMDD 格式
        //String dateFolder = DateUtil.format(dto.getCTime(),"yyyyMMdd");

        // 构建文件路径
        //String filePath = SystemConfig.fileBaseDir + File.separator + dateFolder + File.separator  + dto.getFileName();
        File file = new File(dto.getFilePath());

        if (!file.exists()) {
            throw new CustomException(RestMsg.FILE_NOT_EXISTS);
        }

        try {
            // 获取文件的字节流
            byte[] fileContent = Files.readAllBytes(Paths.get(dto.getFilePath()));

            // 设置响应头，确保文件名在下载时保持中文
            HttpHeaders headers = new HttpHeaders();
            headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + URLEncodeUtil.encode(dto.getFileName()));

            logRepo.createAsync(LOG_TYPE, "下载文件->" + dto.getFileName());
            return ResponseEntity.ok()
                    .headers(headers)
                    .contentType(org.springframework.http.MediaType.APPLICATION_OCTET_STREAM)
                    .body(fileContent);
        } catch (IOException e) {
            exceptionLogRepo.createAsync(LOG_TYPE, e.getMessage(), Arrays.toString(e.getStackTrace()));
            throw new CustomException(RestMsg.DOWNLOAD_FAILED);
        }
    }

    public RestResult getFileInfo(List<String> fileIds) {
        List<FileDTO> dto = fileRepo.getList(fileIds);
        if(dto == null) {
            return RestResult.fail(RestMsg.FILE_NOT_EXISTS);
        }
        return RestResult.success(Linq.mapList(dto, FileMapping.INSTANCE::dto2Info), 0);
    }
}
